home *** CD-ROM | disk | FTP | other *** search
/ Collection of Internet / Collection of Internet.iso / protocol / standard / network / utf / utf_code / text0000.txt < prev   
Encoding:
Text File  |  1993-07-14  |  5.6 KB  |  183 lines

  1.                        Subject:                               Time:4:34 PM
  2.   OFFICE MEMO          ATM C Implementation                   Date:9/3/91
  3. Here is an implementation of the ATM algorithm, for those interested.
  4. Any feedback would be welcome.--Mark
  5.  
  6. /////////////////////////////////////////////////////////////////
  7. // A Transformation Method
  8. // Author:    Mark Davis
  9. // Date:    August 30, 1991
  10. // The following is a C test implementation of the ATM algorithm
  11. // described in the C0 committee report (see that text for
  12. // details as to the purpose and requirements).
  13. // The details of the algorithm are somewhat changed from that
  14. // report, to correct some bugs and take into account some
  15. // results of the WG2 meeting.
  16. /////////////////////////////////////////////////////////////////
  17.  
  18. #include <STDIO.H>
  19. #include <TYPES.h>
  20.  
  21. typedef unsigned char ubyte;
  22. typedef unsigned short ushort;
  23. typedef unsigned long ucs;
  24. typedef short index;
  25. typedef short bufferLength;
  26. enum {false,true};
  27. typedef unsigned char Boolean;
  28.  
  29. #define c0Start 0x00
  30. #define c0End    0x20
  31. #define g0Start 0x21
  32. #define g0End    0x7E
  33. #define c1Start 0x7F
  34. #define c1End    0x9F
  35. #define g1Start 0xA0
  36. #define g1End    0xFF
  37. #define uStart    0x100
  38.  
  39. #define g0Count (c1Start - g0Start)
  40. #define g1Count (uStart  - g1Start)
  41. #define c0Count (g0Start - c0Start)
  42. #define c1Count (g1Start - c1Start)
  43.  
  44. #define gCount    (g0Count + g1Count)
  45. #define cCount    (c0Count + c1Count)
  46.  
  47. #define section0 0x000000A0
  48. #define section1 0x00000100
  49. #define section2 0x00004016
  50. #define section3 0x00038E2E
  51. #define section4 0xFFFFFFFF
  52.  
  53. #define break0    0xA0
  54. #define break1    0xA1
  55. #define break2    0xF6
  56. #define break3    0xFC
  57. #define break4    0x100
  58.  
  59. #define errorChar 0xFFFFFFFF
  60.  
  61. /////////////////////////////////////////////////////////////////
  62. // SkipTable is used to map a contiguous range onto values that
  63. // do not include control bytes.
  64. // It maps the values from 0 to 256 as follows:
  65. //    0                ..    g0Count-1            =>    g0Start..g0End
  66. //    g0Count            ..    gCount-1            =>    g1Start..g1End
  67. //    gCount            ..    gCount+c0Count-1    =>    c0Start..c0End
  68. //    gCount+c0Count    ..    g1End                =>    c1Start..c1End
  69. // UnskipTable reverses the effect of SkipTable.
  70. // The last two ranges are not, strictly speaking, necessary,
  71. // but make it injective and surjective, providing
  72. // predictability for out-of-range cases.
  73. // Call FillSkipTable before using any other routine.
  74. /////////////////////////////////////////////////////////////////
  75.  
  76. ubyte    SkipTable [256];
  77. ucs        UnskipTable [256];
  78.  
  79. void FillSkipTables (void) {
  80.     index    c;
  81.     for (c = 0; c < 256; c++) {
  82.         if (c < g0Count)
  83.             SkipTable[c] = (ubyte)(c + g0Start);
  84.         else if (c < gCount)
  85.             SkipTable[c] = (ubyte)(c - g0Count + g1Start);
  86.         else if (c < (gCount + c0Count))
  87.             SkipTable[c] = (ubyte)(c - gCount + c0Start);
  88.         else
  89.             SkipTable[c]
  90.                 = (ubyte)(c - (gCount + c0Count) + c1Start);
  91.         UnskipTable[SkipTable[c]] = c;
  92.     };
  93. };
  94.  
  95. /////////////////////////////////////////////////////////////////
  96. // The procedure ToATM takes a UCS character (0..4G) and maps it
  97. // to a sequence of bytes that do not include control characters
  98. // (C0 or C1), SPACE, or DEL.
  99. // The length of the sequence can be from 1 to 5 bytes, depending
  100. // on the first byte.
  101. /////////////////////////////////////////////////////////////////
  102.  
  103. void ToAtm(ucs ch, ubyte* a, bufferLength *len) {
  104.     ubyte *chPtr;
  105.     chPtr = a;
  106.     if (ch < section0) {
  107.         chPtr += (*len = 1);
  108.         *--chPtr = (ubyte) ch;
  109.     } else if (ch < section1) {
  110.         chPtr += (*len = 2);
  111.         *--chPtr = (ubyte) ch;
  112.         *--chPtr = break0;
  113.     } else if (ch < section2) {
  114.         chPtr += (*len = 2);
  115.         ch -= section1;
  116.         *--chPtr = SkipTable[ch % gCount]; ch /= gCount;
  117.         *--chPtr = (ubyte)(break1 + ch);
  118.     } else if (ch < section3) {
  119.         chPtr += (*len = 3);
  120.         ch -= section2;
  121.         *--chPtr = SkipTable[ch % gCount]; ch /= gCount;
  122.         *--chPtr = SkipTable[ch % gCount]; ch /= gCount;
  123.         *--chPtr = (ubyte)(break2 + ch);
  124.     } else {
  125.         chPtr += (*len = 5);
  126.         ch -= section3;
  127.         *--chPtr = SkipTable[ch % gCount]; ch /= gCount;
  128.         *--chPtr = SkipTable[ch % gCount]; ch /= gCount;
  129.         *--chPtr = SkipTable[ch % gCount]; ch /= gCount;
  130.         *--chPtr = SkipTable[ch % gCount]; ch /= gCount;
  131.         *--chPtr = (ubyte)(break3 + ch);
  132.     };
  133. };
  134.  
  135. /////////////////////////////////////////////////////////////////
  136. // The procedure FromATM takes a sequence of ATM bytes (as
  137. // generated by ToATM) and maps it to the UCS character (0..4G)
  138. // that generated it.
  139. // Note that there are a number of byte sequences that cannot
  140. // be produced by the ATM algorithm, and are invalid input.
  141. // As written, this procedure checks for some of the obvious
  142. // invalid values, such as insufficient bufferLength (based on
  143. // the first byte), but does not do full-fledged checking for
  144. // invalid sequences (such as <A0,21>).
  145. /////////////////////////////////////////////////////////////////
  146.  
  147. ucs FromAtm(ubyte** bufferStart, bufferLength maxLength) {
  148.     register ubyte        c, *a;
  149.     ucs                    result;
  150.  
  151.     if (maxLength < 1) return errorChar;
  152.     a = *bufferStart;
  153.     c = *a++;
  154.     result = 0;
  155.     if (c < break0) {
  156.         result = c;
  157.     } else if (c < break1) {
  158.         result = *a++;
  159.     } else if (c < break2) {
  160.         if (maxLength < 2) return errorChar;
  161.         result = c - break1;
  162.         result *= gCount; result += UnskipTable[*a++];
  163.         result += section1;
  164.     } else if (c < break3) {
  165.         if (maxLength < 3) return errorChar;
  166.         result = c - break2;
  167.         result *= gCount; result += UnskipTable[*a++];
  168.         result *= gCount; result += UnskipTable[*a++];
  169.         result += section2;
  170.     } else {
  171.         if (maxLength < 5) return errorChar;
  172.         result = c - break3;
  173.         result *= gCount; result += UnskipTable[*a++];
  174.         result *= gCount; result += UnskipTable[*a++];
  175.         result *= gCount; result += UnskipTable[*a++];
  176.         result *= gCount; result += UnskipTable[*a++];
  177.         result += section3;
  178.     };
  179.     *bufferStart = a;    // pass back new starting point
  180.     return result;
  181. };
  182.  
  183.